Many data processing systems utilize multithreaded processes for processing data. The allocation of private memory in a multithreaded process can cause unwanted contention on the process heap. FIG. 1 is a diagram that illustrates the address space 10 for a multithreaded process. As is seen, there are a plurality of threads with their associated stacks 12a-12n, each of which can access the shared heap 14. Included within the address space 10 is data 16 and code 18. A function such as malloc is typically used to allocate memory for all threads in a process. Dynamically allocated data in a multithreaded process comes in two main forms: (1) thread shared (shared between one or more threads) and (2) thread local (used by only one thread).
Using functions like malloc( ) and free( ) to allocate memory which is shared between threads makes sense since malloc and free are for process wide memory. Using malloc and free for thread local memory is not a good choice since only one thread will make use of the memory and yet all threads must coordinate there access to the shared heap. Since malloc and free do not support pools, the contention on an underlying memory management facility can become unacceptably high. It is possible to assign pools within the heap for a thread or group of threads. In so doing the contention between threads can be reduced. Pools reduce the contention by spreading out the allocations and frees over the number of pools. While pools are useful, they have their own set of problems.
If pools are created on top of the standard malloc and free interface, large blocks of memory of the heap will likely need to be allocated. Allocating smaller amounts and assigning them to a pool can increase the contention on the underlying memory management facility and potentially negate any benefit from having separate pools.
Allocating large blocks of memory from the process heap will likely lead to wasted space in one or more forms. There is also a balance that needs to be met between the number of threads per pool and the contention on the pool. Having too many threads in a pool means higher contention and having too few threads in a pool will likely lead to wasted space. Also, when more than one thread uses the same pool then the chances of inter-thread memory corruptions increases. Therefore, it would be advantageous for reliability and problem determination efforts to ensure that each thread used a separate pool.
Another option is to create an anonymous memory region (e.g., by mapping in /dev/zero, etc.) for each pool. Such memory regions could in theory grow in the same way as the process heap grows which would reduce the need to allocate large blocks of memory for a pool. Having a separate memory region for each pool means that the address space for a pool will be continguous and thus the large blocks of memory required when using the same memory region (i.e., the process heap) is not necessary. The problem with having a separate memory region for each pool is that the number of memory regions can easily get out of hand. In a process that has 1000 threads, and where there is one memory pool per thread we could end up with 1000 regions of memory for thread local memory and 1000 regions of memory for the corresponding thread stacks (thread stacks use one region of memory).
Having a large number of memory regions can lead to unwanted overhead in the kernel to manage this many memory regions. Also, the more memory regions in use, the worse the address space fragmentation is.
Accordingly, what is desired is a method and system of reducing contention for thread stack that does not increase the number of memory regions needed for a processor. The method and system should be easily implemented, cost effective and adaptable to existing system. The present invention addresses such a need.